import math
from random import random

import deck
import kohutils
import koh

# debug mode flags. Disable at least debug before release
debug = True # debug mode.
test_double = False # test multiple cards in hand; idk if it works yet
# end debug mode flags

# disabling any debug flags if debug mode disabled
if not debug:
    test_double = False

number_of_players = 0
number_of_decks = ''
players = []
card_deck = deck.Deck()
playing_field = deck.Field()

def setup():
    global number_of_players
    
    done = False
    while not done:
        try:      
            number_of_players = int(input("Number of Players (2-4): "))
            
            if not kohutils.restrict_input(number_of_players, 2, 4):
                raise ValueError
            
            elif number_of_players == 4:
                number_of_decks = input("Number of Decks to use (default 1, max 2): ")
                if number_of_decks == '':
                    number_of_decks = 1
                else:
                    number_of_decks = int(number_of_decks)
                    
                if not kohutils.restrict_input(number_of_decks, 1, 2):
                    raise ValueError
                elif number_of_decks == 2:
                    card_deck.generateDeck()
            
        except ValueError:
            print("Invalid Input")
            continue

        else:
            done = True
            for i in range(5):
                card_deck.shuffle()
            for i in range(number_of_players):
                player = koh.Player(i + 1)
                card_deck.deal_to(player.face_down_cards,3)
                card_deck.deal_to(player.face_up_cards,3)
                card_deck.deal_to(player.hand,5)
                players.append(player)

            # DOES NOT WORK YET... I THINK
            if test_double and debug:
                card_deck.cards.append(players[0].hand.pop())
                card_to_double = players[0].hand[0]
                for card in card_deck.cards:
                    if card[1] == card_to_double[1]:
                        players[0].hand.append(card)
                        card_deck.cards.remove(card)
                        break
    print()

def preparation():

    complete = False
    
    for player in players:
        print("Player", player.number)
        print("You may now switch any card in your hand with any face-up card.")
        
        while not complete:
            print("At any time, you may enter ", end = '')
            print("'done' (without the quotes and lowercase) to finish.")

            # Sort player's hand
            player.sort_hand()
            
            player.show_face_up_cards()
            player.show_hand(True)

            tableCard = input("Index of face-up card: ")

            # Now check input. If done then break. If invalid continue + warnusr
            if tableCard == 'done':
                complete = True
                break
            else:
                try:
                    tableCard = int(tableCard)
                except ValueError:
                    print("Invalid Input")
                    continue
                else:
                    if not kohutils.restrict_input(tableCard, 1, 3):
                        print("Invalid Input")
                        continue
                
            handCard = input("Index of card from hand: ")
            if handCard == 'done':
                complete = True
                break
            else:
                try:
                    handCard = int(handCard)
                except ValueError:
                    print("Invalid Input")
                    continue
                else:
                    if not kohutils.restrict_input(handCard, 1, 5):
                        print("Invalid Input")
                        continue

            # All tests passed. Now do the switch.
            tableCard -= 1
            handCard -= 1
            success = player.switch_face_up_card(tableCard, handCard)
            if not success:
                print("Invalid Input")
                continue
            else:
                print("Done!\n")
             
        complete = False
        kohutils.clear_screen()

def choose_start_player():
    # Choose a first player at random
    # global player_start # debug only; for checking if it works
    player_start = math.floor(random() * number_of_players)

    # Now shift the position of the players accordingly
    for i in range(player_start):
        head_player = players.pop(0)
        players.append(head_player)

    print("Player", player_start + 1, "will start the game\n")
    

def turn(turn_number):
    # Now let's get this show on the road!
    for player in players:
        # to control the end of the player's turn.
        play_end = False
        print('Player ', player.number, ', it\'s your turn!', sep = '')
        
        print("Current top card:", ''.join(playing_field.top_card()))

        while not play_end:
            top = player.hand_length()

            cards_to_play = []
            if player.hand:
                player.sort_hand()
                player.show_hand()
                card_grp = 0
            else:
                player.show_face_up_cards()
                card_grp = 1

            print("Enter the card that you wish to play.")
            print("Alternatively, enter one of the following actions: ")
            if turn_number > 1:
                print("pickup,", end = ' ')
            print("checkdiscarded, checkothertop") # implement these actions
            # finish implementing interpreter (implement actions)

            # debug commands
            if debug:
                print("Debug commands: discardhand, draw, skip, quit")
                print("To play a card you MUST type: play")
            
            action = input("Action: ")

            if action == 'pickup':
                if turn_number == 1:
                    print("Invalid Input\n")
                    continue
                
                print("Implement me ASAP! D:D:D:")
                
            elif action == 'checkdiscarded':
                playing_field.show_discarded()
                
            elif action == 'checkothertop':
                print("Not implemented yet. Nag the dev to get it done.")
                print("(he might kill you though)")

            elif debug and action != 'play':
                # Debug mode only
                if action == 'skip':
                    play_end = True

                elif action == 'discardhand':
                    playing_field.add_discarded(player.hand)
                    player.hand = []
                    print("Hand Discarded")

                elif action == 'draw':
                    amount = int(input("# of cards: "))
                    card_deck.deal_to(player.hand, amount)

                elif action == 'quit':
                    # returning True or the player number == someone won
                    return True
                
                else:
                    print("Invalid Command")

                # End Debug mode only
                
            else:
                if debug and action == 'play':
                    action = input("Card: ")
                try:
                    # NOTE: make so that user only has to input the value
                    #       of the card

                    # if playing from empty hand
                    if card_grp == 1 and kohutils.restrict_input(int(action),
                                                                 1, 3):
                        # check if valid card to play
                        if player.get_face_up_cards()[int(action)]:
                            card_value = player.get_face_up_cards()[int(action)][1]
                            top_card = playing_field.last_card_played[1]

                        else:
                            card = player.get_face_down_cards()[int(action)]
                            card_value = card[1]
                            top_card = playing_field.last_card_played[1]

                        # implement special card thing here

                        if card_value < top_card:
                            raise ValueError
                            
                        cards_to_play.append(int(action) - 1)
                        cards_played = player.play_card(card_grp, cards_to_play)
                        if not cards_played:
                            raise ValueError
                        elif not cards_played[0]:
                            raise ValueError
                        
                        playing_field.add_played(cards_played)
                        play_end = True
                        continue

                    # implement special card thing here

                    if not kohutils.restrict_input(len(action), 2, 3):
                        raise ValueError

                    if len(action) > 2:
                        card_value = int(action[1:len(action)])
                        if card_value > 10:
                            raise ValueError

                    # now turn the input into a tuple
                    card_req = (action[0], action[1:len(action)])

                    # count the number of that card in hand
                    card_req_count = player.hand_count(card_req)
                        
                    if not card_req_count:
                        raise ValueError

                    if playing_field.played:
                        played_cards = playing_field.played
                        if card_req[1] < played_cards[len(played_cards) - 1][1]:
                            raise ValueError
                    
                    # if there are multiple cards
                    if card_req_count > 1:
                        input_correct = False
                        while not input_correct:
                            print("There are", card_req_count, end = ' ')
                            print(card_req[1], "'s in your hand.", sep = '')
                            print("How many do you wish to play?")
                            print("Type any letter to cancel")

                            prompt = ''.join(['(1-', str(card_req_count), '):'])
                            card_req_play = int(input(prompt))
                            success = kohutils.restrict_input(card_req_play,
                                                              1,
                                                              card_req_count)
                            if not success:
                                print("Invalid Input")
                                continue
                            
                            else:
                                input_correct = True
                                break

                        for i in range(card_req_play):
                            card_index = player.hand.index(card_req) + i
                            cards_to_play.append(card_index)

                        cards_played = player.play_card(card_grp, cards_to_play)
                        if not cards_played:
                            raise ValueError
                        else:
                            playing_field.add_played(cards_played)
                            play_end = True

                    # single card.         
                    else:
                        card_index = player.hand.index(card_req)
                        cards_to_play.append(card_index)
                        cards_played = player.play_card(card_grp,
                                                        cards_to_play)
                        if not cards_played:
                            raise ValueError
                        else:
                            playing_field.add_played(cards_played)
                            play_end = True

                except ValueError:
                    print("Invalid Input\n")
                    continue

        if player.hand_length() < 5:
            draw_amount = 5 - player.hand_length()
            card_deck.deal_to(player.hand, draw_amount)
        kohutils.clear_screen()
        

def main():
    if __name__ == '__main__':
        setup()
        preparation()

# Uncomment the following line to enable randomization of starting player
        choose_start_player()
        winner = False
        turn_number = 0
        while not winner:
            turn_number += 1
            winner = turn(turn_number)

        if winner == True:
            print("Game ended due to tester's command")

        elif winner:
            print("Player ", winner, ", you won!", sep = '')
            # implement leaderboard

        else:
            print("An unknown error occurred. Quitting...")

# Main Program
main()
